<?php

namespace App\Service\VendorClient\ShopHouNiaoApi;
use App\Service\Code\Normal;
use App\Service\BaseService;
use App\Service\HttpServer\Http;

/**
 * 候鸟供应商SDK
 * @author chenshubo
 * 商城API
 */

class ShopHouNiaoApiClient extends BaseService
{
    private $clientId       = null;
    private $clientToken    = null;
    private $clientPaySign  = null;
    private $urlNormal      = null;
    private $urlPay         = null;
    private $clientConfig   = null;
    
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct() 
    {
        $clientConfig = config('api.houniao');
        $this->clientConfig = $clientConfig;
        $acount = $clientConfig['acount'];
        $this->urlNormal        = $acount['API_DOMAIN'].$acount['API_ROUTE']['normal'];
        $this->urlPay           = $acount['API_DOMAIN'].$acount['API_ROUTE']['pay'];
        $this->clientId         = $acount['userId'];
        $this->clientToken      = $acount['token'];
        $this->clientPaySign    = $acount['paySign'];
    }
    
    /**
     * 查询余额
     */
    public function queryBalance( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'capitals.queryBalance';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    
    /**
     * 获取所有省市区
     */
    public function getRegions( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'base.getRegions';
        $params = array_merge($params,$where);
        return $this->execute($params);       
    }
    
    /**
     * 创建订单
     */
    public function createOrder( $param = [] ) 
    {
        $res = $this->getHouNiaoSupplierAreaRegion($param['order']);
        if( $res['code'] != Normal::SUC ) {
            return $res;
        }
        $orderInfo      = $res['data'];
        $supplierGoods  = $param['supplierGoodsInfo'];
        $goodsList      = $orderInfo['goods'];
        //下单商品
        $userGoodsList  = $supplierGoods['userGoodsList'];
        //原始商品
        $goodsList      = $supplierGoods['goodsList'];
        
        //下单商品组
        $orderGoods = [];
        foreach ($userGoodsList as $item ) {
            $item = array_map(function( & $val ) use ($goodsList) {
                $val['goodsSku'] = $goodsList[$val['goodsSku']]['supplierSKUCode'];
                $goodsBatchNo = $val['goodsBatchNo'];
                if( $goodsBatchNo != '基准' ) {
                    $goodsBatchNo = str_replace(['年','月'],['-',''], $goodsBatchNo);
                    $val['startExpDate'] = $goodsBatchNo;
                    $val['endExpDate'] = $goodsBatchNo;
                } else {
                    $val['startExpDate'] = $val['endExpDate'] = '';
                }
                return $val;
            },$item);
            $orderGoods = array_merge($orderGoods,$item);
            unset($item);
        }
        
        //调用候鸟接口进行创建订单
        $orders = [];
        $orders['cusOrderNo']     = $orderInfo['supplier_psn'];
        $orders['userName']       = $orderInfo['buyerRealName'];
        $orders['userPhone']      = $orderInfo['buyerPhone'];
        $orders['IDCard']         = $orderInfo['buyerIdCard'];
        $orders['userAddress']    = $orderInfo['receiveAddress'];
        $orders['orderRemarks']   = $orderInfo['orderRemarks'];
        $orders['province']       = $orderInfo['province'];
        $orders['city']           = $orderInfo['city'];
        $orders['district']       = $orderInfo['district'];
        $orders['goods']          = $orderGoods;
        
        //提交上游接口数据
        $createData = [];
        $createData['orders'][]   = $orders;
        $createData['orders']     = json_encode($createData['orders']);
        $createData['method']     = 'order.createOrder';
        return $this->execute($createData);
    }
    
    /**
     * 处理候鸟供应商省市区数据
     */
    protected function getHouNiaoSupplierAreaRegion( $param = [] )
    {
        //处理收货地址问题
        $province   = $param['province'];
        $city       = in_array($param['city'],['北京市','上海市','天津市','重庆市']) ? '市辖区' : $param['city'] ;
        $district   = $param['district'];
    
        //组装省市区地址
        $param['region']   = [
            'province'  => $province,
            'city'      => $city,
            'district'  => $district,
        ];
    
        //如果是外部商户则从redis计算数据
        if( !isset($param['isOpen']) || $param['isOpen'] != 1 ) {
            $areaIds = [$province,$city,$district];
            $areaInfo = Area::instance()->lists([
                ['area_id','in',$areaIds],
            ]);
    
            if( empty($areaInfo) ) {
                return Normal::returnCode(Normal::FAIL,"省市区信息获取失败");
            }
    
            $areaInfo = array_column($areaInfo, 'area_name','area_id');
            $province  = $areaInfo[$province] ?? '';
            $city      = $areaInfo[$city] ?? '';;
            $district  = $areaInfo[$district] ?? '';
            if( empty($province) || empty($city) || empty($district) ) {
                return Normal::returnCode(Normal::FAIL,"未找到省市区数据，请核对");
            }
    
            //组装省市区地址
            $param['region']   = [
                'province'  => $province,
                'city'      => $city,
                'district'  => $district,
            ];
        }
    
        //获取候鸟省份数据
        $houniaoProvinceList = $this->getHouniaoRegions();
    
        //获取province code
        if( isset($houniaoProvinceList[$province]) ) {
            $provinceCode = $houniaoProvinceList[$province];
        } else if( isset($houniaoProvinceList[$province."市"]) ) {
            $provinceCode = $houniaoProvinceList[$province."市"];
        } else if( isset($houniaoProvinceList[$province."省"]) ) {
            $provinceCode = $houniaoProvinceList[$province."省"];
        } else if( isset($houniaoProvinceList[$province."自治区"]) ) {
            $provinceCode = $houniaoProvinceList[$province."自治区"];
        } else {
            return Normal::returnCode(Normal::FAIL,"省份不正确，请核对！");
        }
    
        //获取city code
        $cityList = BaseService::instance()->getRedisObj()->hGet('houniao_region',$provinceCode);
        if( empty($cityList) ) {
            return Normal::returnCode(Normal::FAIL,"市信息获取失败-1");
        }
    
        $cityList = json_decode($cityList,true);
        $cityMap  = array_column($cityList, 'areaId','areaName');
        if( !isset($cityMap[$city]) ) {
            return Normal::returnCode(Normal::FAIL,"市信息获取失败-2");
        }
    
        $cityCode = $cityMap[$city];
    
        //获取地区
        $districtMap = array_column($cityList[$cityCode]['list'], 'areaId','areaName');
    
        //获取district code
        if( isset($districtMap[$district]) ) {
            $districtCode = $districtMap[$district];
            //如果是区
        } else if( isset($districtMap[$district."区"]) ) {
            $districtCode = $districtMap[$district."区"];
            //如果是县
        } else if( isset($districtMap[$district."县"]) ) {
            $districtCode = $districtMap[$district."县"];
            //如果是县升级为区
        } else if( strpos($district, "县") !== false && isset($districtMap[str_replace("县","",$district)."区"]) ) {
            $districtCode = $districtMap[str_replace("县","",$district)."区"];
        } else {
            return Normal::returnCode(Normal::FAIL,"地区不正确，请核对！");
        }
    
        $param['province']  = $provinceCode;
        $param['city']      = $cityCode;
        $param['district']  = $districtCode;
        return Normal::returnCode(Normal::SUC,"查询成功",$param);
    }
    
    /**
     * 获取候鸟省市区信息(缓存)
     */
    public function getHouniaoRegions()
    {
        $redis   = BaseService::instance()->getRedisObj();
        $cache_key = 'houniao_region';
        $list = $redis->hGet($cache_key,'0');
        if( !empty($list) ) {
            return json_decode($list,true);
        }
        
        $regions = $this->getRegions();
        if( $regions['code'] == 0 && !empty( $regions['regions']) ) {
            $list = treeKeys($regions['regions'], 0, 'areaId', 'pid');
            if( !empty($list) ) {
    
                $firstAreaInfo = array_column($list, 'areaId','areaName');
                $redis->hSet($cache_key,'0',json_encode($firstAreaInfo,JSON_UNESCAPED_UNICODE));
                
                //分散省份数据
                foreach ($list as $province_code => $data ) {
                    $redis->hSet($cache_key,(string)$province_code,json_encode($data['list'],JSON_UNESCAPED_UNICODE));
                }
            }
    
            return $firstAreaInfo;
        }
    
        return false;
    }
    
    /**
     * 获取订单物流信息
     */
    public function getOrderExpress( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'order.getExpress';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 获取商品库存
     */
    public function getStock( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'goods.getStock';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 批量获取商品库存
     */
    public function getStocks( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'goods.getStocks';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 获取商品价格
     */
    public function getPrice( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'goods.getPrice';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 批量获取商品价格
     */
    public function getPrices( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'goods.getPrices';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 获取商品列表
     */
    public function goodsList( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'goods.goodsList';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 获取分类
     */
    public function getCategory( $where = [] ){
        // 组装提交参数(数组)
        $params['method'] = 'base.getCategory';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 通过分类ID获取商品列表
     */
    public function getGoodsListByCategoryId( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'goods.getGoodsListByCategoryId';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 通过分类ID获取商品列表
     */
    public function getGoodsList( $where = [] ) {
        
        // 组装提交参数(数组)
        $params['method'] = 'goods.goodsList';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    
    /**
     * 获取商品详情
     */
    public function getGoodsDetailBySku( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'goods.getGoodsDetailBySku';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 获取所有快递方式
     */
    public function getExpressList( $where = [] ) {
        // 组装提交参数(数组)
        $params['method'] = 'base.getExpress';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 余额支付接口
     */
    public function orderPay( $where = [] ) {
        // 组装提交参数(数组)
        $params['method']   = 'pay.balance';
        $params['version']  = !empty($where['version']) ? $where['version'] : '1.0';
        $params['time']     = time();
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * 取消订单，只可以取消未支付订单。已支付订单联系客服人员处理
     */
    public function orderCancel( $where = [] ) {
        // 组装提交参数(数组)
        $params['method']   = 'order.cancel';
        $params = array_merge($params,$where);
        return $this->execute($params);
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $params = [] ) 
    {
        $start_time = microtime(true);
        //支付接口
        if( in_array($params['method'], ['pay.balance']) ) {
            $params['service'] = $params['method'];
            unset($params['method']);
            $params['client_id'] = $this->clientId;
            $url = $this->urlPay;
            $params['sign'] = strtoupper(Http::getSign($params,$this->clientPaySign));
            $params = Http::toXml($params);
            return Normal::returnCode(Normal::SUC,"获取成功",[
                'url'       => $url,
                'data'      => $params,
                'format'    => 'form-data'
            ]);
        } else if( in_array($params['method'], ['base.getRegions']) ) {
            $params['clientId']    = $this->clientId;
            $params['clientToken'] = $this->clientToken;
            $url = $this->urlNormal;
            $res = Http::apiRequest($url, $params,'post');
            return json_decode($res, true);
        } else {
            $params['clientId']    = $this->clientId;
            $params['clientToken'] = $this->clientToken;
            $url = $this->urlNormal;
            return Normal::returnCode(Normal::SUC,"获取成功",[
                'url'       => $url,
                'data'      => $params,
                'format'    => 'x-www-form-urlencoded'
            ]);
        }
    }
}
